package reflect;

import org.testng.annotations.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLOutput;

public class TestCar {
    //获取Class对象
    @Test
    public void test1() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //类名.class
        Class class1 = Car.class;
        //对象.getClass()
        Class class2 = new Car().getClass();
        //Class.forname("全路径")
        Class class3 = Class.forName("reflect.Car");

        //实例化
        Car car = (Car) class1.getDeclaredConstructor().newInstance();
    }

    @Test
    public void test2() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class class4 = Car.class;
        //用反射获取构造方法
        //.getDeclaredConstructor()  //获得所有方法
        Constructor[] constructors = class4.getConstructors(); //只获得public方法
        for (Constructor constructor : constructors) {
            System.out.println("构造方法" + constructor.getName() + "参数个数" + constructor.getParameterCount());
        }
        //用public有参数构造器构造对象
        Constructor constructor1 = class4.getConstructor(String.class, int.class, String.class);
        Car car1 = (Car) constructor1.newInstance("宝马", 10, "白色");
        System.out.println(car1);

        //用private有参数构造器构造对象
        Constructor constructor2 = class4.getDeclaredConstructor(String.class, int.class);
        constructor2.setAccessible(true);
        Car car2 = (Car) constructor2.newInstance("奔驰", 20);
        System.out.println(car2);
    }

        //用反射获取属性
    @Test
    public void test3() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class class4 = Car.class;
        Car car = (Car) class4.getConstructor().newInstance();
        //获取所有public属性
        Field[] fields = class4.getFields();
        //获取所有属性
        Field[] fields1 = class4.getDeclaredFields();
        for (Field field : fields1){
            System.out.println(field);
            if(field.getName().equals("name")){
                field.setAccessible(true);
                field.set(car,"五菱");
            }
            System.out.println(field.getName());
            System.out.println(car);

        }
    }
        //用反射获取方法
    @Test
    public void test4() throws InvocationTargetException, IllegalAccessException {
        Car car = new Car("aito",3,"银色");
        Class class1 = car.getClass();
        //public方法
        Method[] methods = class1.getMethods();
        for (Method method : methods){
            System.out.println(method);
            if(method.getName().equals("toString")){
                String invoke = (String) method.invoke(car);
                System.out.println("toString执行了"+invoke);
            }
        }
        //private方法
        Method[] methods2 = class1.getDeclaredMethods();
        for (Method method : methods){
            System.out.println(method);
            if(method.getName().equals("run")){
                method.setAccessible(true);
                method.invoke(car);
            }
        }
    }

}
